package com.txby.platformApi.component.web;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jck.mybatis.log.GlobalLogAnnotation;
import com.jck.mybatis.util.MyBatisReflectUtil;
import com.jck.tools.ChkUtil;
import com.jck.tools.Getrandom;
import com.jck.tools.MD5Util;
import com.txby.platformCore.component.service.CommonController;
import com.txby.platformCore.component.util.DingdongCloudUtil;
import com.txby.platformCore.data.CommonApiModelMapExt;
import com.txby.platformCore.entity.DctNrsCardCnf;
import com.txby.platformCore.entity.ProductDeviceInit;
import com.txby.platformCore.entity.SickDetailInfo;
import com.txby.platformCore.entity.TxbySysApiUser;
import com.txby.platformCore.entity.VisitorUser;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 安全令牌相关
 * 
 * @author 作者 jacking
 * @date 2017年6月22日 上午10:37:26
 */
@SuppressWarnings("all")
@RestController
@Api(value = "安全令牌相关", description = "安全令牌相关")
@RequestMapping("/user")
public class TxbySysApiUserVerifyController extends CommonController {
	private static Logger log = Logger.getLogger(TxbySysApiUserVerifyController.class);

	@ApiOperation(value = "服务注册或更新", notes = "服务注册或更新-说明")
	@PostMapping("/signIn/{type}/{userName}/{passWord}/{updateSign}")
	public Map signIn(@PathVariable("type") Integer type, @PathVariable("userName") final String userName,
			@PathVariable("passWord") String passWord, @PathVariable("updateSign") String updateSign,
			String oldPassWord) {
		CommonApiModelMapExt map = new CommonApiModelMapExt();
		TxbySysApiUser gau = null;
		String md5UpdateSign = MD5Util.getMD5ofStr(userName + passWord, 2);
		System.out.println(propertySourceConfig.getIsProMode());
		if (propertySourceConfig.getIsProMode() != null && propertySourceConfig.getIsProMode().equals("true")
				&& !md5UpdateSign.equals(updateSign)) {
			return new CommonApiModelMapExt(1, "安全标识验证不通过", null, null, null);
		} else {
			Map paratmers = new HashMap<>();
			paratmers.put("userName", userName);
			gau = (TxbySysApiUser) this.mBaseDao.findBySqlUniqueObject("select * from "
					+ MyBatisReflectUtil.tablename(TxbySysApiUser.class) + " where userName=#{pojo.userName} ",
					TxbySysApiUser.class, paratmers);
		}
		if (gau != null) {
			if (!ChkUtil.isEmpty(oldPassWord) && MD5Util.getMD5ofStr(oldPassWord, 2).equals(gau.getPassWord())) {
				gau.setPassWord(MD5Util.getMD5ofStr(passWord, 2));
				this.mBaseDao.updateObject(gau);
				map = getCreateTokenByTxbySysApiUserAndPutCache(gau);
				map.put(CommonApiModelMapExt.ERRCODE, 1);
				map.put(CommonApiModelMapExt.ERRMSG, "用户已存在,更新成功请牢记新的密码");
			} else {
				map = new CommonApiModelMapExt(1, "用户已存在，旧密码不正确或旧密码为空", null, null, null);
			}

		} else {

			if (userName.startsWith("txbyApi_")) {
				gau = new TxbySysApiUser();
				gau.setUserName(userName);
				gau.setPassWord(MD5Util.getMD5ofStr(passWord, 2));
				this.mBaseDao.saveObject(gau);
				map = getCreateTokenByTxbySysApiUserAndPutCache(gau);
				map.put(CommonApiModelMapExt.ERRCODE, 0);
				map.put(CommonApiModelMapExt.ERRMSG, "注册成功,用户名进行增加");
			} else {
				map = new CommonApiModelMapExt(1, "用户名称不合法", null, null, null);
			}
		}
		return map;
	}

	/**
	 * 
	* @Title: verifyCheck 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param type
	* @param @param userName
	* @param @param passWord
	* @param @param updateSign
	* @param @param isDemo 
	* @param @return    设定文件 
	* @return Map    返回类型 
	* @throws
	 */
	@ApiOperation(value = "服务验证", notes = "服务验证-说明")
	@GetMapping("/verifyCheck/{type}")
	public Map verifyCheck(@PathVariable("type") Integer type, @RequestParam(required = true) String userName,
			@RequestParam(required = true) String passWord, @RequestParam(required = true) String updateSign,Integer isDemo,Integer isVisitor) {
		CommonApiModelMapExt map = new CommonApiModelMapExt();
		TxbySysApiUser gau = null;
         
		boolean  demoFlag=false;
		boolean  visitor=false;
		
		if(!ChkUtil.isEmpty(isDemo)&&isDemo==1) {
			
			demoFlag=true;
		}else{
			
			if(!ChkUtil.isEmpty(isVisitor)&&isVisitor==1) visitor=true;
			
		}
		
	
		/*
		 * globalLog.saveLog(new HashMap(){{ put("message",
		 * "my name is jiaojing"); put("type", "respondType"); }});
		 */
		
		Map params=new HashMap();
		params.put("userName", userName);
		String md5UpdateSign = MD5Util.getMD5ofStr(userName + passWord, 2);
		if (propertySourceConfig.getIsProMode() != null && propertySourceConfig.getIsProMode().equals("true")
				&& !md5UpdateSign.equals(updateSign)) {
			return new CommonApiModelMapExt(1, "安全标识验证不通过", null, null, null);
		} else {
			gau = (TxbySysApiUser) this.mBaseDao
					.findBySqlUniqueObject(
							"select * from " + MyBatisReflectUtil.tablename(TxbySysApiUser.class)
									+ " where userName=#{pojo.userName} and status=0 ",
							TxbySysApiUser.class, params);
		}
		if (gau != null) {
			if (MD5Util.getMD5ofStr(passWord, 2).equals(gau.getPassWord())) {
				map = getCreateTokenByTxbySysApiUserAndPutCache(gau);
			} else {
				map = new CommonApiModelMapExt(1, "用户已存在，旧密码不正确", null, null, null);
			}
		} else {
//			if(demoFlag) userName=demoDeviceSN;
			ProductDeviceInit pdi = getProductDeviceInit(userName);
			if(demoFlag){
				pdi=new ProductDeviceInit();
				pdi.setBedNO("test");
			}
			if (pdi != null && passWord.equals(MD5Util.getMD5ofStr(userName, 2))) {
				gau = new TxbySysApiUser();
				gau.setId(userName);
				gau.setPassWord(passWord);
				if(demoFlag){
					map =getDemoCreateTokenByTxbySysApiUserAndPutCache(gau);
				}else{
					if(visitor){
						VisitorUser vu=new VisitorUser();
						gau.setId(userName);
						gau.setPassWord(passWord);
						 map= getCreateTokenByWaitvstAndPutCache(vu);
					}else{
						map = getCreateTokenByTxbySysApiUserAndPutCache(gau);
						
					}
				}
			} else {
				map = new CommonApiModelMapExt(1, "设备未绑定", null, null, null);
			}

		}
		return map;
	}

	@ApiOperation(value = "访客服务验证", notes = "访客服务验证-说明")
	@GetMapping("/verifyCheckByVisitor/{type}")
	public Map verifyCheckByVisitor(@PathVariable("type") Integer type,@RequestParam(required=true) String mobileNO,String passWord,String verifyCode,
			@RequestParam(required=true)  String updateSign)  {
		CommonApiModelMapExt map=new CommonApiModelMapExt();
		VisitorUser	 gau=null;
		String tips="";
		if(StringUtils.isBlank(verifyCode)){
			verifyCode="";
			tips="手机号与密码不匹配";
		}
		if(StringUtils.isBlank(passWord)){
			passWord="";
			tips="手机号与验证码不匹配";
		}
		passWord=new String(Base64.getDecoder().decode(passWord.getBytes()));
		String md5UpdateSign=MD5Util.getMD5ofStr(mobileNO+passWord+verifyCode, 2);
		if(propertySourceConfig.getIsProMode()!=null&&propertySourceConfig.getIsProMode().equals("true")&&!md5UpdateSign.equals(updateSign)){
			return   new CommonApiModelMapExt(1,  "安全标识验证不通过", null, null, null);
		}else{
			gau=(VisitorUser) this.mBaseDao.findBySqlUniqueObject("select * from "+MyBatisReflectUtil.tablename(VisitorUser.class)+" where mobileNO=#{pojo.mobileNO} and status=0 ", VisitorUser.class, new HashMap(){{
				put("mobileNO", mobileNO);
			}});
		}
		Object o=this.springEhcacheUtil.get(this.apiTokenCachName, mobileNO);
		if(gau!=null) {
			if(null!=passWord&&MD5Util.getMD5ofStr(passWord, 2).equals(gau.getPassWord())){
				map= getCreateTokenByVisitorUserAndPutCache(gau);
			}else{
				if(o!=null&&verifyCode!=null&&verifyCode.equals(o)){
				 map= getCreateTokenByVisitorUserAndPutCache(gau);
				}else{
					map =new CommonApiModelMapExt(1,  tips, null, null, null);
				}
			}
		}else{
			if(o!=null&&verifyCode!=null&&verifyCode.equals(o)){
				 gau=new VisitorUser();
				 gau.setStatus(0);
				 gau.setMobileNO(mobileNO);
				 gau.setPassWord(MD5Util.getMD5ofStr(mobileNO.substring(mobileNO.length()-6,mobileNO.length()), 2));
				 this.mBaseDao.saveObject(gau);
				 map= getCreateTokenByVisitorUserAndPutCache(gau);
			}else{
				map=new CommonApiModelMapExt(1,  tips, null, null, null);;
			}
		}
		return map;
	}
	@ApiOperation(value = "保存访客信息", notes = "保存访客信息-说明")
	@PostMapping("/saveVisitorInfo/{type}/{token}")
	public Map saveVisitorInfo(@PathVariable("type") Integer type,@PathVariable("token") String token,@RequestParam  String mobileNO,@RequestParam String passWord,@RequestParam String name)  {
		CommonApiModelMapExt map=new CommonApiModelMapExt();
		passWord=new String(Base64.getDecoder().decode(passWord.getBytes()));
		VisitorUser	 gau =(VisitorUser) this.mBaseDao.findBySqlUniqueObject("select * from "+MyBatisReflectUtil.tablename(VisitorUser.class)+" where mobileNO=#{pojo.mobileNO} and status=0 ", VisitorUser.class, new HashMap(){{
				put("mobileNO", mobileNO);
			}});
 
		if(gau!=null) {
			passWord=MD5Util.getMD5ofStr(passWord, 2);
			gau.setPassWord(passWord);
			gau.setName(name);
			this.mBaseDao.updateObject(gau);
		}else{ 
				map=new CommonApiModelMapExt(1,  "访客用户不存在", null, null, null);;
		}
		return map;
	}
	@ApiOperation(value = "修改访客信息密码", notes = "修改访客信息密码-说明")
	@PostMapping("/updateVisitorPassWord/{type}/{token}")
	public Map updateVisitorPassWord(@PathVariable("type") Integer type,@PathVariable("token") String token,@RequestParam  String mobileNO,@RequestParam String oldPassWord,@RequestParam String newPassWord)  {
		newPassWord=new String(Base64.getDecoder().decode(newPassWord.getBytes()));
		oldPassWord=new String(Base64.getDecoder().decode(oldPassWord.getBytes()));
		CommonApiModelMapExt mm = chekTokenCahceValid(token, type);
		if (!isTokenValid) {
			return mm;
		}
		VisitorUser	 gau =(VisitorUser) this.mBaseDao.findBySqlUniqueObject("select * from "+MyBatisReflectUtil.tablename(VisitorUser.class)+" where mobileNO=#{pojo.mobileNO} and status=0 ", VisitorUser.class, new HashMap(){{
			put("mobileNO", mobileNO);
		}});
		
		if(gau!=null) {
			
			if(MD5Util.getMD5ofStr(oldPassWord, 2).equals(gau.getPassWord())){
				gau.setPassWord(MD5Util.getMD5ofStr(newPassWord, 2));
				this.mBaseDao.updateObject(gau);
			}else{
				mm.put(CommonApiModelMapExt.ERRCODE, 1);
				mm.put(CommonApiModelMapExt.ERRMSG, "旧密码不正确");
			}
			
			mm.put(CommonApiModelMapExt.ERRCODE, 0);
			mm.put(CommonApiModelMapExt.ERRMSG, "修改成功");
		}else{ 
			mm.put(CommonApiModelMapExt.ERRCODE, 1);
			mm.put(CommonApiModelMapExt.ERRMSG, "访客用户不存在");
		}
		return mm;
	}

	

	@ApiOperation(value = "访客服务发送验证码", notes = "访客服务发送验证码-说明")
	@PostMapping("/sendVisitSmsCode/{type}")
	public Map sendVisitSmsCode(@PathVariable("type") Integer type, @RequestParam(required = true) String mobileNO,
			@RequestParam(required = true) String updateSign) {
		CommonApiModelMapExt mm = new CommonApiModelMapExt();
		/*
		 * globalLog.saveLog(new HashMap(){{ put("message",
		 * "my name is jiaojing"); put("type", "respondType"); }});
		 */
		String md5UpdateSign = MD5Util.getMD5ofStr(mobileNO, 2);
		if (propertySourceConfig.getIsProMode() != null && propertySourceConfig.getIsProMode().equals("true")
				&& !md5UpdateSign.equals(updateSign)) {
			return new CommonApiModelMapExt(1, "安全标识验证不通过", null, null, null);
		} else {
			String verifyCode = Getrandom.randomByNumberString(6);
			JSONObject result = JSON.parseObject(DingdongCloudUtil.sendYzmDefaultByVerifyCode(mobileNO, verifyCode));
			if (result.getInteger("code") == 1) {
				mm = new CommonApiModelMapExt(0, "短信发送成功", null, null, null);
				putTokenCache(mobileNO, verifyCode);
			} else {
				mm = new CommonApiModelMapExt(1, "短信发送失败", null, null, null);
			}
		}
		return mm;
	}

	@GetMapping("/verifiCheckDctNrs/{type}/{token}")
	@GlobalLogAnnotation(logType = 2, discription = "检查医护人员登入验证")
	public Map verifiCheckDctNrs(@PathVariable("type") Integer type, @PathVariable("token") String token,
			@RequestParam(required = true) String deviceSN, @RequestParam(required = true) String loginName,
			@RequestParam(required = true) String passWord) {

		CommonApiModelMapExt mm = chekTokenCahceValid(token, type);
		try {
			if (!isTokenValid) {
				return mm;
			}
			if (ChkUtil.isEmpty(loginName) || ChkUtil.isEmpty(passWord)) {
				mm.put(CommonApiModelMapExt.ERRCODE, 1);
				mm.put(CommonApiModelMapExt.ERRMSG, "参数不正确");
				return mm;
			}
			Map params = new HashMap();
			params.put("loginName", loginName);
			ProductDeviceInit pdi = getProductDeviceInit(deviceSN);
			SickDetailInfo sdi = this.getSickDetailInfo(deviceSN);
			DctNrsCardCnf dc = null;
			String sql = "SELECT * FROM " + this.mBaseDao.tableName(DctNrsCardCnf.class)
					+ " WHERE 1=1 and (cardNO =#{pojo.loginName} or jobNO =#{pojo.loginName}) ";
			if (pdi != null) {
				sql += " and deptId='" + pdi.getDeptId() + "'";
				dc = (DctNrsCardCnf) this.mBaseDao.findBySqlUniqueObject(sql, DctNrsCardCnf.class, params);

			}
			
			if(token.startsWith("demo:")){
				mm.put(CommonApiModelMapExt.ERRCODE, 0);
				mm.put(CommonApiModelMapExt.ERRMSG, "验证成功");
				mm.put("data", sdi);
				mm.put("nurseName", "演示护士");
				return mm;
			}

			if (dc != null && dc.getPassWord().equals(passWord)) {
				mm.put(CommonApiModelMapExt.ERRCODE, 0);
				mm.put(CommonApiModelMapExt.ERRMSG, "验证成功");
				mm.put("data", sdi);
				mm.put("nurseName", dc.getName());
				pdi.setUpdateTime(new Date());
				this.mBaseDao.updateObject(pdi);
			} else {
				if (dc == null) {
					mm.put(CommonApiModelMapExt.ERRCODE, 1);
					mm.put(CommonApiModelMapExt.ERRMSG, "工号不存在");
				} else {

					mm.put(CommonApiModelMapExt.ERRCODE, 1);
					mm.put(CommonApiModelMapExt.ERRMSG, "密码错误，请重新输入");
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			mm.put(CommonApiModelMapExt.ERRCODE, 5000);
			mm.put(CommonApiModelMapExt.ERRMSG, "系统开小差，稍后重试");
		}

		return mm;
	}

	/**
	 * 患者信息登录验证，后6位身份证号
	 */

	@GetMapping("/verifiCheckSick/{type}/{token}")
	@GlobalLogAnnotation(logType = 2, discription = "检查患者人员登入验证")
	public Map verifiCheckSick(@PathVariable("type") Integer type, @PathVariable("token") String token,
			@RequestParam(required = true) String deviceSN) {

		CommonApiModelMapExt mm = chekTokenCahceValid(token, type);
		try {
			if (!isTokenValid) {
				return mm;
			}
			SickDetailInfo sdi = this.getSickDetailInfo(deviceSN);
			boolean verifiFlag = false;
			if (sdi != null) {
				mm.put(CommonApiModelMapExt.ERRCODE, 0);
				mm.put(CommonApiModelMapExt.ERRMSG, "登录验证成功");
				mm.put("data", sdi);
				return mm;
			} else {
				ProductDeviceInit pdi=getProductDeviceInit(deviceSN);
				if(!ChkUtil.isEmpty(pdi)&&pdi.getDeviceUseType()==0){
					Map temp=new HashMap();
					String sickAreaName=pdi.getSickAreaName()==null?"":pdi.getSickAreaName();
					String bedNO=pdi.getBedNO()==null?"":pdi.getBedNO();
					temp.put("sickAreaName", pdi.getSickAreaName());
					temp.put("bedNO", pdi.getBedNO());
					mm.put(CommonApiModelMapExt.ERRCODE, 0);
					mm.put(CommonApiModelMapExt.ERRMSG, "患者信息不存在返回设备绑定基本信息");
					mm.put("data", temp);
					return mm;
				}else{
					mm.put(CommonApiModelMapExt.ERRCODE, 4202);
					mm.put(CommonApiModelMapExt.ERRMSG, "患者信息不存在");
					return mm;
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			mm.put(CommonApiModelMapExt.ERRCODE, 1);
			mm.put(CommonApiModelMapExt.ERRMSG, "系统异常");
		}

		return mm;
	}

	/**
	 * 根据deviceSN获取组织下所有开卡的护士信息
	 */

	@GetMapping("/getAllDotNrsAccountInfo/{type}/{token}")
	@GlobalLogAnnotation(logType = 2, discription = "检查组织下所有开卡的护士信息")
	public Map getAllDotNrsAccountInfo(@PathVariable("type") Integer type, @PathVariable("token") String token,
			@RequestParam(required = true) String deviceSN) {

		CommonApiModelMapExt mm = chekTokenCahceValid(token, type);
		try {
			if (!isTokenValid) {
				return mm;
			}
			String sql = "SELECT * FROM " + this.mBaseDao.tableName(DctNrsCardCnf.class) + " WHERE 1=1 and type=0   ";
			ProductDeviceInit pdi = getProductDeviceInit(deviceSN);
			List<DctNrsCardCnf> dctNrsList = new ArrayList<>();
			if (pdi != null) {
				sql += " and deptId='" + pdi.getDeptId() + "'";
				dctNrsList = this.mBaseDao.findBySql(sql, DctNrsCardCnf.class, null);
			} else {
				mm.put(CommonApiModelMapExt.ERRCODE, 1);
				mm.put(CommonApiModelMapExt.ERRMSG, "此设备没有初始化绑定");
				return mm;
			}
			if(null!=dctNrsList&&dctNrsList.size()>0){
				mm.put(CommonApiModelMapExt.ERRCODE, 0);
				mm.put(CommonApiModelMapExt.ERRMSG, "查询成功");
			}else{
				mm.put(CommonApiModelMapExt.ERRCODE, 4500);
				mm.put(CommonApiModelMapExt.ERRMSG, "无数据");
			}
			/*
			 * for(DctNrsCardCnf d:dctNrsList){ if(d.getSex()==0){
			 * d.setSex("男"); }else{ d.setSex("女"); }
			 * 
			 * }
			 */
			mm.put("data", dctNrsList);
			return mm;
		} catch (Exception e) {
			e.printStackTrace();
			mm.put(CommonApiModelMapExt.ERRCODE, 1);
			mm.put(CommonApiModelMapExt.ERRMSG, "系统异常");
		}

		return mm;
	}

}